package com.fub.guidance;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Vertex {

	private final String id;
	private final String buildingId;
	private final Point postion;
	private final Type type;
	private final String label;
	private Map<String, String> properties = new HashMap<String, String>();
	private List<Edge> edges;

	public enum Type {
		ROOM, ELEVATOR, STAIRS, ENTRANCE, LIFT, CORIDOR, DOOR, UNKNOWN;
	}

	/**
	 * Constructs an new Node.
	 * 
	 * @param id
	 *            the id of this node
	 * @param buildingId
	 *            the id of this building
	 * @param position
	 *            the position of this node
	 * @param type
	 *            the type of this node
	 * @param roomLabel
	 *            the label of this node
	 */
	public Vertex(String id, String buildingId, Point position, String type,
			String roomLabel) {
		this.id = id;
		this.postion = position;
		this.buildingId = buildingId;
		this.label = roomLabel;
		if (type.equalsIgnoreCase("room")) {
			this.type = Type.ROOM;
		} else if (type.equalsIgnoreCase("coridor")) {
			this.type = Type.CORIDOR;
		} else if (type.equalsIgnoreCase("door")) {
			this.type = Type.DOOR;
		} else if (type.equalsIgnoreCase("entrance")) {
			this.type = Type.ENTRANCE;
		} else if (type.equalsIgnoreCase("stairs")) {
			this.type = Type.STAIRS;
		} else if (type.equalsIgnoreCase("lift")) {
			this.type = Type.LIFT;
		} else {
			this.type = Type.UNKNOWN;
		}
		this.edges = new ArrayList<Edge>();
	}

	/**
	 * Returns all adjacent nodes of this node.
	 * 
	 * @return all adjacent nodes of this node.
	 */
	public List<Vertex> getAdjacentNodes() {
		List<Vertex> adjacentNodes = new ArrayList<Vertex>();
		for (Edge edge : this.edges) {
			if (edge.getDestinationId().equals(this.id)) {
				adjacentNodes.add(Graph.getInstance().getNodeById(
						edge.getSourceId()));
			} else {
				adjacentNodes.add(Graph.getInstance().getNodeById(
						edge.getDestinationId()));
			}
		}
		return adjacentNodes;
	}

	/**
	 * Returns the building id of this node.
	 * 
	 * @return the building id of this node.
	 */
	public String getBuildingId() {
		return this.buildingId;
	}

	/**
	 * Returns the properties of this node.
	 * 
	 * @return the properties of this node
	 */
	public Map<String, String> getProperies() {
		return this.properties;
	}

	/**
	 * Returns a specific property of this node.
	 * 
	 * @param key
	 *            the name of the property
	 * @return a specific property of this node.
	 */
	public String getProperty(String key) {
		String result = "";
		for (String keyInMap : this.properties.keySet()) {
			if (keyInMap.equals(key)) {
				result = this.properties.get(key);
			}
		}
		return result;
	}

	/**
	 * Returns the id's of all adjacent edges of this node.
	 * 
	 * @return he id's of all adjacent edges of this node
	 */
	public List<Edge> getEdges() {
		return this.edges;
	}

	/**
	 * Returns the id of this node.
	 * 
	 * @return the id of this node.
	 */
	public String getId() {
		return this.id;
	}

	/**
	 * Returns the position of this node.
	 * 
	 * @return the position of this node
	 */
	public Point getPostion() {
		return this.postion;
	}

	/**
	 * Returns the type of this node.
	 * 
	 * @return the type of this node
	 */
	public Type getType() {
		return this.type;
	}

	/**
	 * Returns the label of this node.
	 * 
	 * @return the label of this node
	 */
	public String getLabel() {
		return this.label;
	}

	/**
	 * Returns the position of this node.
	 * 
	 * @return the position of this node
	 */
	public Point getPosition() {
		return this.postion;
	}

	@Override
	public String toString() {
		return this.id + " " + this.label + " " + this.type;
	}

	/**
	 * Adds an edge to this node.
	 * 
	 * @param edge
	 *            the edge, that should be added
	 */
	public void addEdge(Edge edge) {
		this.edges.add(edge);
	}

	/**
	 * Adds properties to this node.
	 * 
	 * @param properties
	 *            the properties, that should be added
	 */
	public void setProperties(Map<String, String> properties) {
		this.properties = properties;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Vertex other = (Vertex) obj;
		if (this.id == null) {
			if (other.id != null)
				return false;
		} else if (this.id != other.id)
			return false;
		return true;
	}
}
